package com.cskaoyan.javase.oop1._5this;

/**
 * this关键字:
 * 引例:
 * 创建一个汽车类，有颜色（color）和速度（speed）两个属性，行为是可以跑（run）。
 * 实现：
 * 在run成员方法中访问速度和颜色两个属性，调用该方法查看结果。
 * 在run成员方法的形参列表中，添加一个局部变量speed，不修改方法体，调用该方法查看结果。
 * 思考：
 * 两次方法调用的结果一样吗？为什么？
 * 如果我想在2中得到1的访问结果，怎么办呢？
 *
 * 当成员方法中的形参变量和成员变量同名时,再在方法中访问该同名变量
 * 结果必然是方法实参传入的取值,这就是一种就近原则
 *
 * 那么在以上情况下,如果还想要访问同名的成员变量,怎么办呢?
 * 显然不做特殊处理是不能达到需求的
 * 这时,我们需要this关键字来帮助我们完成需求
 *
 * this关键字(重点):
 * 概念: 在Java中类中,任何一个成员方法中,其形参列表都会隐式的传入一个参数
 * 传入的是该类的对象,称之为"当前对象"
 * 用this关键字指向这个隐式传入的"当前对象",也就是说,this是一个引用,指向当前对象
 * 在成员方法中,可以用this关键字
 *
 * 重要问题: 何为当前对象呢?
 *      对于初学者而言,要记住
 *      成员方法是需要一个对象来调用的,"对象名.成员方法名()"
 *      那么,谁来调用这个成员方法,谁就是"当前对象"
 *
 * this关键字的作用:
 *      1.(常见) this关键字在成员方法中,用于区分同名的成员变量和局部变量
 *          在成员方法中,如果直接访问同名的成员变量和局部变量,访问的是局部变量(就近原则)
 *          而如果用"this.同名的成员变量和局部变量名"访问的是成员变量
 *
 *     2.(最常见的,你可能没有感觉到的用途)
 *          为什么成员方法中可以无条件访问成员变量?
 *          原因就在于this的隐式传参
 *          任何成员方法中都存在当前类的对象
 *          既然对象已经存在了,访问成员变量是很正常的事情.
 *          而且由于this是隐含的传参,如果不是为了区分同名的成员变量和局部变量,没必要把this.写出来
 *
 *          既然能够访问成员变量,那么访问成员方法也是可以的
 *          static方法和static方法之间是可以互相调用的
 *          非static方法和非static方法(成员方法)之间也是可以互相调用的
 *
 *     3.static方法,不是成员方法,没有this传参,static方法之中没有任何对象,所以static方法之中不能直接访问成员变量,也不能直接调用成员方法
 *
 *
 *     4.(凑数)
 *     在成员方法中只要使用 "this."访问 一个变量，那么该变量一定是成员变量。
 *     在代码比较复杂的情况下，可以显著增加代码可读性。(但这不是必须的,比较少用)
 *
 *
 * @since 10:54
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Car c = new Car();
        // "对象名点"赋值是创建对象完毕之后的赋值方式,它会覆盖掉创建对象过程中的赋值
        // c.speed = 120;
        c.color = "红色";
        // 对于run方法的这一次调用来说,run方法中的隐含传参this,就指向对象c,c就是它的当前对象
        c.run(300);
        System.out.println(c);

        System.out.println("-----------------");
        Car c2 = new Car();
        c2.run(400);
        System.out.println(c2);
    }
}

class Car {
    String color;
    // 显式赋值,是创建对象过程中赋值手段
    double speed = 200;

    public void test() {
        System.out.println(this.color);
        // this是隐含的,写出来不算错,但也没必要
        System.out.println(this.speed);
    }

    public static void testStatic() {
        // System.out.println(color);
    }

    public void run(double speed) {
        System.out.println(this);
        System.out.println(color + "的小汽车嘟嘟嘟的在马路上,以" + this.speed + "km/h的速度奔驰~");
    }
}